package com.dd.cloud.user.req.pres;

import com.alibaba.fastjson.JSON;
import com.dd.cloud.common.annotate.FileSuffix;
import com.dd.cloud.common.constants.PharConstants;
import com.dd.cloud.common.enums.ZkExceptionEnum;
import com.dd.cloud.common.exception.ZekeException;
import com.dd.cloud.common.utils.ObjectUtils;
import com.dd.cloud.common.utils.ValidatorUtils;
import com.dd.cloud.user.req.phar.PresCreateCreamFormulaReq;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import javax.validation.Valid;
import javax.validation.constraints.*;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * @author zk
 */
@Data
@Slf4j
public class PresCreateReq {
    /**
     * 诊断id
     */
    private Integer diagnosticId;

    /**
     * 问诊id
     */
    private Integer consultId;

    /**
     * 是否ai开方 1是 0否 默认1
     */
    private Integer isAiPres = 1;

    /**
     * 就诊卡id
     */
    private String medId;

    /**
     * 如果是女性角色, 是否怀孕 0否 1是
     */
    private Integer pregnant = 0;

    /**
     * 药房id
     */
    @NotNull(message = "药房id不能为空")
    private Integer pharId;

    /**
     * 科室名称
     */
    private String depName;

    /**
     * 症状
     */
    @NotEmpty(message = "症状不能为空")
    @Size(max = 1500, message = "症状长度最长1500个字符")
    private String symptomList;

    /**
     * 疾病
     */
    @NotEmpty(message = "疾病不能为空")
    @Size(max = 20, message = "疾病长度最长20个字符")
    private String disease;

    /**
     * 辩证诊断
     */
    private String dialectical;

    /**
     * 每日剂数
     */
    @NotNull(message = "每天/每次用量不能为空")
    private Integer dayDose;

    /**
     * 总剂数
     */
    @NotNull(message = "总剂数/每天次数不能为空")
    @Max(value = 100, message = "总剂数不能超过100")
    private Integer allDose;

    /**
     * 包装量 条件必填
     * 每袋药业装量，请填入数字如 200，
     * 150,100，50 (包装量请传入大于等
     * 于 50并且小于等 280)建议设置为可
     * 选项
     */
    private Integer packagenum;

    /**
     * 药品金额 必填 分单位
     */
    private Integer money;

    /**
     * 药品原价金额
     */
    private Integer presOriginalMoney;

    /**
     * 折扣药品金额 分单位
     */
    private Integer discountMoney;

    /**
     * 诊疗费 必填 分单位
     */
    private Integer consultationFee = 0;

    /**
     * 服务费 必填 分单位
     */
    private Integer serviceFee = 0;

    /**
     * 物流费 分单位
     */
    private Integer expensesFee = 0;

    /**
     * 代煎费 分单位
     */
    private Integer fryingFee = 0;

    /**
     * 膏方费/蜂密价格 根据type区分
     */
    private Integer otherFee = 0;

    /**
     * 备注
     */
    private String remark;

    /**
     * 类型 我方剂型
     */
    @NotNull(message = "加工类型不能为空")
    private Integer presType;

    /**
     * 预计出粉量
     */
    private String outPut;

    /**
     * 出量天数
     */
    private String useDay;

    /**
     * 目数
     */
    private String num;

    /**
     * 快递方式
     */
    @NotNull(message = "快递是否显示不能为空")
    private Integer deliveryIsDisplay;

    /**
     * 医嘱
     */
    @Size(max = 500, message = "医嘱字符不能超过500个字符")
    private String advice;

    /**
     * 疗期医嘱
     */
    @Size(max = 500, message = "疗期医嘱字符不能超过500个字符")
    private String treatAdvice;

    /**
     * 药品用法说明
     */
    @Size(max = 200, message = "用法补充不能超过200个字符")
    private String drugUsage;

//    /**
//     *
//     */

    /**
     * 每剂次数
     */
    private Integer doseNum;

    /**
     * 每袋药业装量 默认280g  //粉剂有字符串
     */
    private Integer drugDose;

    /**
     * 表外字段, 待审药品列表
     */
    @Valid
    @NotNull(message = "处方药品不能为空")
    private List<PresCreateDrugsReq> tcms;

    /**
     * 膏方列表(选择膏方必须要有)
     */
    private List<PresCreateCreamFormulaReq> creamFormulaReqs;

    /**
     * openid 微信jsapi支付,app支付时需要
     */
    private String openid;

    /**
     * 支付方式
     */
    @NotBlank(message = "支付方式不能为空")
    private String payType;

    /**
     * 处方编码
     */
    private String tencode;

    /**
     * 应用来源, 默认公众号, 如果是小程序, 值为applet
     */
    private String apply;

    /**
     * 是否修改处方信息 0否 1是
     */
    private Integer isUpdate = 0;

    /**
     * 是否需要支付 0否 1是
     */
    private Integer isPay = 0;

    /**
     * 开放给患者端
     */
    private Integer paramsType = 0;

    /**
     * 签名
     */
//    @NotBlank(message = "签名不能为空")
    @FileSuffix(head = false)
    private String sign;

    /**
     * 二次签名
     */
    @FileSuffix(head = false)
    private String confirmSign;

    /**
     * 来源类型 1医生处方 2智能处方 3医生处方(问诊) 4智能处方(问诊)
     */
    private Integer sourceType;

    /**
     * 是否显示药品 0否 1是
     */
    private Integer drugShow = 1;

    /**
     * 是否显示药品用量 0否 1是
     */
    private Integer drugDoseShow = 1;

    /**
     * 中医诊断名
     */
    private String zyName;

    /**
     * 中医诊断编码
     */
    private String zyCode;

    /**
     * 患者信息
     */
    private String patientJson;

    /**
     * 患者收货地址信息
     */
    private String addrJson;

    /**
     * 患者信息
     */
    @Valid
    private PresPatientReq patientReq;

    /**
     * 患者收货地址信息
     */
    private PresPatientAddrReq addrReq;

    /**
     * 重量 后端自用
     */
    private BigDecimal weightKg;

    /**
     * 起订量
     */
    private String minWeight;

    /**
     * 地址
     */
    private String address;

    /**
     * 过敏史
     */
    private String drugAllergyHistory;

    /**
     * 诊断名
     */
    private String diagnosticName;

    /**
     * 线下疾病选择
     */
    private String offlineDisease;

    /**
     * 是否为免费问诊开方 1.是 0.否
     */
    private Integer isFree = 0;

    /**
     * 是否代煎
     */
    private Integer isFrying;


    /**
     * 验证参数
     */
    public static PresCreateReq castandValid(Map<String, Object> map, Integer flag) {
        PresCreateReq req;
        switch (flag) {
            case PharConstants.Flag.HJT:
                PresCreateHjtReq hjtReq = null;
                try {
                    hjtReq = ObjectUtils.convertMap2Bean(map, PresCreateHjtReq.class);
                    List<PresCreateDrugsReq> list = ObjectUtils.convertListMap2ListBean((List<Map<String, Object>>) map.get("tcms"), PresCreateDrugsReq.class);
                    hjtReq.setTcms(list);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (hjtReq == null) {
                    throw new ZekeException(ZkExceptionEnum.PARAMETER_ERROR, "宏济堂药房参数转换异常");
                }
                ValidatorUtils.verify(hjtReq, PresCreateHjtReq.class);
                if (hjtReq.getIsdaijian() == 1 && hjtReq.getProcesstype() != 1) {
                    throw new ZekeException(ZkExceptionEnum.PARAMETER_ERROR, "选择代煎则加工类型必须选择汤药");
                }
                hjtReq.setIsPay(1);
                req = hjtReq;
                break;
            case PharConstants.Flag.DSL:
                PresCreateDslReq dslReq = null;
                try {
                    dslReq = ObjectUtils.convertMap2Bean(map, PresCreateDslReq.class);
                    List<PresCreateDrugsReq> list = ObjectUtils.convertListMap2ListBean((List<Map<String, Object>>) map.get("tcms"), PresCreateDrugsReq.class);
                    dslReq.setTcms(list);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (dslReq == null) {
                    throw new ZekeException(ZkExceptionEnum.PARAMETER_ERROR, "大参林药房参数转换异常");
                }
                ValidatorUtils.verify(dslReq, PresCreateDslReq.class);
                if (dslReq.getPayStatus() == 1) {
                    dslReq.setIsPay(1);
                }
                req = dslReq;
                break;
            case PharConstants.Flag.KM:
                PresCreateKmReq kmReq = null;
                try {
                    kmReq = ObjectUtils.convertMap2Bean(map, PresCreateKmReq.class);
                    List<PresCreateDrugsReq> list = ObjectUtils.convertListMap2ListBean((List<Map<String, Object>>) map.get("tcms"), PresCreateDrugsReq.class);
                    kmReq.setTcms(list);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (kmReq == null) {
                    throw new ZekeException(ZkExceptionEnum.PARAMETER_ERROR, "康美药房参数转换异常");
                }
                ValidatorUtils.verify(kmReq, PresCreateKmReq.class);
                if (kmReq.getType() == 3 && kmReq.getWjType() == null) {
                    throw new ZekeException(ZkExceptionEnum.PARAMETER_ERROR, "选择丸剂则必须选择丸剂类型");
                }
                if (kmReq.getIsInvoice() == 1) {
                    if (kmReq.getLookUp() == null || kmReq.getInvomoney() == null) {
                        throw new ZekeException(ZkExceptionEnum.PARAMETER_ERROR, "选择开发票必须传发票抬头以及发票金额");
                    }
                }
                if (kmReq.getPayStatus() == 1) {
                    kmReq.setIsPay(1);
                }
                req = kmReq;
                break;
            case PharConstants.Flag.XX:
                PresCreateXxReq xxReq = null;
                try {
                    xxReq = ObjectUtils.convertMap2Bean(map, PresCreateXxReq.class);
                    List<PresCreateDrugsReq> list = ObjectUtils.convertListMap2ListBean((List<Map<String, Object>>) map.get("tcms"), PresCreateDrugsReq.class);
                    xxReq.setTcms(list);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (xxReq == null) {
                    throw new ZekeException(ZkExceptionEnum.PARAMETER_ERROR, "香雪药房参数转换异常");
                }
                ValidatorUtils.verify(xxReq, PresCreateKmReq.class);
                xxReq.setIsPay(1);
                req = xxReq;
                break;
            case PharConstants.Flag.STORE:
                PresCreateOtherReq otherReq = null;
                try {
                    otherReq = ObjectUtils.convertMap2Bean(map, PresCreateOtherReq.class);
                    List<PresCreateDrugsReq> list = ObjectUtils.convertListMap2ListBean((List<Map<String, Object>>) map.get("tcms"), PresCreateDrugsReq.class);
                    otherReq.setTcms(list);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (otherReq == null) {
                    throw new ZekeException(ZkExceptionEnum.PARAMETER_ERROR, "其他药房参数转换异常");
                }
                ValidatorUtils.verify(otherReq, PresCreateOtherReq.class);
                if (otherReq.getPayStatus() == 1) {
                    otherReq.setIsPay(1);
                }
                req = otherReq;
                break;
            case PharConstants.Flag.HR:
                PresCreateHrReq hrReq = null;
                try {
                    hrReq = ObjectUtils.convertMap2Bean(map, PresCreateHrReq.class);
                    List<PresCreateDrugsReq> list = ObjectUtils.convertListMap2ListBean((List<Map<String, Object>>) map.get("tcms"), PresCreateDrugsReq.class);
                    hrReq.setTcms(list);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (hrReq == null) {
                    throw new ZekeException(ZkExceptionEnum.PARAMETER_ERROR, "华润三九药房参数转换异常");
                }
                ValidatorUtils.verify(hrReq, PresCreateHrReq.class);
                hrReq.setIsPay(1);
                req = hrReq;
                break;
            case PharConstants.Flag.YF:
                PresCreateYfReq yfReq = null;
                try {
                    yfReq = ObjectUtils.convertMap2Bean(map, PresCreateYfReq.class);
                    List<PresCreateDrugsReq> list = ObjectUtils.convertListMap2ListBean((List<Map<String, Object>>) map.get("tcms"), PresCreateDrugsReq.class);
                    yfReq.setTcms(list);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (yfReq == null) {
                    throw new ZekeException(ZkExceptionEnum.PARAMETER_ERROR, "一方制药药房参数转换异常");
                }
                ValidatorUtils.verify(yfReq, PresCreateHrReq.class);
                yfReq.setIsPay(1);
                req = yfReq;
                break;
            case PharConstants.Flag.HST:
                PresCreateHstReq hstReq = null;
                try {
                    hstReq = ObjectUtils.convertMap2Bean(map, PresCreateHstReq.class);
                    List<PresCreateDrugsReq> list = ObjectUtils.convertListMap2ListBean((List<Map<String, Object>>) map.get("tcms"), PresCreateDrugsReq.class);
                    hstReq.setTcms(list);
                } catch (Exception e) {
                    throw new ZekeException(ZkExceptionEnum.PARAMETER_ERROR, "和顺堂药房参数转换异常");
                }
                req = hstReq;
                break;

            default:
                throw new ZekeException(400, "未知药房参数");
        }
        req.setPatientReq(JSON.parseObject(req.getPatientJson(), PresPatientReq.class));
        req.setAddrReq(JSON.parseObject(req.getAddrJson(), PresPatientAddrReq.class));
        if (req.getSourceType() == null) {
            req.setSourceType(req.getIsAiPres() == 1 ? 2 : 1);
        }
        log.info("req:{},\njson:{}", req, req.getPatientJson());
        return req;
    }
}
